//模拟抢票
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<unistd.h>
#include<pthread.h>
#include"lockGuard.hpp"

using namespace std;

pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

#define NUM 4

class threadData{
public:
    threadData(int number){
        threadname = "thread-" + to_string(number);
        
    }    
public:
    string threadname;
};

int tickets = 3000;

void *getTicket(void *args){
    threadData *td = static_cast<threadData *>(args);
    const char *name = td->threadname.c_str();
    while(true){
        pthread_mutex_lock(&lock);
        if(tickets>0){
            usleep(1000);
            printf("who=%s, get a ticket: %d\n",name,tickets);
            tickets --;
            pthread_mutex_unlock(&lock);
        }else{
            pthread_mutex_unlock(&lock);
            break;
        }
        usleep(13); // 我们抢到了票，我们会立马抢下一张吗？其实多线程还要执行得到票之后的后续动作。usleep模拟

    }
    printf("%s ... quit\n",name);
    return nullptr;
}

void fun(){
    static int cnt=0;
    cnt++;
    printf("hello fun()\n");
}

// void *getTicket(void *args){
//     threadData *td = static_cast<threadData *>(args);
//     const char *name = td->threadname.c_str();
//     while(true){
//         {
//             LockGuard lockguard(&lock);
//             if(tickets>0){
//                 usleep(1000);
//                 printf("who=%s, get a ticket: %d\n",name,tickets);
//                 tickets--;
//             }
//             else 
//                 break;
//         }
//         usleep(13);
//     }
//     printf("%s ... quit\n",name);
//     return nullptr;
// }

int main(){
    
    vector<pthread_t> tids;
    vector<threadData *> thread_datas;
    for(int i=1;i<=NUM;i++){
        pthread_t tid;
        threadData *td = new threadData(i);
        thread_datas.push_back(td);
        pthread_create(&tid,nullptr,getTicket,thread_datas[i-1]);
        tids.push_back(tid);
    }

    sleep(10);
    for(auto thread : tids){
        pthread_join(thread,nullptr);
    }

    for(auto td:thread_datas){
        delete td;
    }
    
    return 0;
}